昨天我們寫好了測試的 model,今天就來用他實作吧。
我們先從最簡單的 main_bp
開始。
from flask import url_for
from tests.helper import TestModel
class IndexPageTest(TestModel):
def setUp(self) -> None:
super().setUp()
self.route = url_for("main.index_page")
def test_get_with_no_auth(self):
res = self.get()
self.assertEqual(res.status_code, 200)
self.assertIn(b"Login", res.data)
def test_get_with_auth(self):
res = self.get(login="user")
self.assertEqual(res.status_code, 200)
self.assertIn(b"Dashboard", res.data)
他繼承了 TestModel
,然後重寫了 setUp
,用原先的 setUp
再加上一行指定 self.route
,這樣昨天寫的 get
、post
就都可以用了,而這個 self.route
是用 url_for
處理的。
後面我們用了兩個測試,一個是在沒登入的情況下抓這個頁面,另一個是在有登入的情況下。我們分別看他們有沒有回傳 200,然後後面我們再使用 assertIn
來確定 "Login"
和 "Dashboard"
有沒有在回傳的 HTML 裡面 (res.data
),我們會拿這個來當作判斷依據是因為到時候網頁的 navbar 會根據有沒有登入來決定要用怎麼樣子的,如果沒有登入當然就是顯示 login、register 等等,有登入的話就是 dashboard、寫文章之類的按鈕,這邊要注意的是,res.data
是一個 bytes 型別,所以我們前面用的 assertIn
也要跟著他用 bytes 型別。
結束了 main_bp
的測試,我們來繼續看 user_bp
的。這裡就會有很多路徑,我們一個一個看,首先是登入頁面。
class LoginPageTest(TestModel):
def setUp(self) -> None:
super().setUp()
self.route = url_for("user.login_page")
self.user_data_bad_wrong_password = {"username": "user", "password": "bad"}
def test_get_with_no_auth(self):
res = self.get()
self.assertEqual(res.status_code, 200)
self.assertIn(b"Login", res.data)
def test_get_with_auth(self):
res = self.get(login="user")
self.assertEqual(res.status_code, 200)
self.assertIn(b"Dashboard", res.data)
def test_post_ok(self):
res = self.post(data=self.user_data)
self.assertEqual(res.status_code, 200)
self.assertIn(b"Dashboard", res.data)
def test_post_bad_wrong_password(self):
res = self.post(data=self.user_data_bad_wrong_password)
self.assertEqual(res.status_code, 200)
self.assertIn(b"Wrong username or password.", res.data)
在 setUp
裡面,我們一樣先寫好這裡的 self.route
,然後額外放了一個錯的帳號密碼。這邊要記得,我們在 TestModel
的 setUp
就有先生出兩個測試帳號,所以他們用一般的登入是可以的。
我們一樣先分別用沒登入和有登入的狀況去抓這個頁面,這個部分跟剛剛一樣。接下來輪到 post
,我們先做一次 OK 的測試,就是拿正確的登入資料塞給他,那他應該要讓我們過,這是我們的期望,後面的 assertIn
是因為我們用 follow_redirects
,所以登入後理論上會被重新導向到 dashboard 之類的地方,也就是說一定會有 navbar,所以用這個來判斷。再來是用錯誤的資料塞給網頁,那他應該要出現打錯密碼的訊息,也就是後面 assertIn
的內容。
接下來我們來看看註冊頁面的測試。
class RegisterPageTest(TestModel):
def setUp(self) -> None:
super().setUp()
self.route = url_for("user.register_page")
self.register_data_ok = {
"username": "user2",
"password": "useruser",
"repeat_password": "useruser",
"email": "user@a.a",
}
self.register_data_bad_too_short_password = {
"username": "user2",
"password": "short",
"repeat_password": "short",
"email": "user@a.a",
}
def test_get_with_no_auth(self):
res = self.get()
self.assertEqual(res.status_code, 200)
self.assertIn(b"Login", res.data)
def test_get_with_auth(self):
res = self.get(login="user")
self.assertEqual(res.status_code, 200)
self.assertIn(b"Dashboard", res.data)
def test_post_ok(self):
res = self.post(data=self.register_data_ok)
self.assertEqual(res.status_code, 200)
self.assertIn(b"Login", res.data)
def test_post_bad_too_short_password(self):
res = self.post(data=self.register_data_bad_too_short_password)
self.assertEqual(res.status_code, 200)
self.assertIn(b"The password must contain at least 6 characters.", res.data)
在 setUp
我們做了差不多的事情,這次我們準備了一份可以註冊的使用者資料跟一份密碼過短的,這個密碼過短的部分是 Flask-WTF 的工作,他會幫我們驗證。
一開始我們一樣看一下正常去抓網頁會不會有正常反應,當然加入登入和未登入兩個狀態。接下來我們先丟正確的資料給他,所以正常來說應該是註冊成功了,他應該會把我們導向到登入頁面之類的,但是還沒有登入,所以 navbar 上面還是會有 Login。而第二個則是密碼過短,Flask-WTF 會幫我們驗證到然後丟出錯誤,所以我們會收到這個訊息,然後 flash
出去,所以用 assertIn
來確定有沒有這個錯誤訊息,這個錯誤訊息是可以自訂的,也可以在 Flask-WTF 自己修改。
在 user_bp
當然不只有這兩個路徑,但我們就示範一些,不然太多也太重複了。